package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.bean.Category;
import com.itheima.bean.Setmeal;
import com.itheima.bean.SetmealDish;
import com.itheima.dao.SetmealDao;
import com.itheima.dto.SetmealDto;
import com.itheima.exception.CustomException;
import com.itheima.service.CategoryService;
import com.itheima.service.SetmealDishService;
import com.itheima.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Tang
 * @date 2023/2/21
 */
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealDao, Setmeal> implements SetmealService {

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
//    @Lazy  //懒加载注解：打破循环依赖，注入的对象只有使用的时候才会进行初始化
    private CategoryService categoryService;

    /**
     * 新增套餐包含菜品信息
     * @param setmealDto
     */
    @Override
    public void saveWithDishs(SetmealDto setmealDto) {
        //0.开启事务
        //1.直接调用继承父类的新增方法，保存套餐基本信息到setmeal表中
        this.save(setmealDto);

        //2.循环遍历套餐菜品列表数据，关联套餐id
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        for (SetmealDish setmealDish : setmealDishes) {
            setmealDish.setSetmealId(setmealDto.getId());
        }

        //3.批量保存套餐菜品列表数据到setmeal_dish表中
        setmealDishService.saveBatch(setmealDishes);
    }

    /**
     * 分页
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public Page<SetmealDto> findPage(Integer page, Integer pageSize, String name) {
        //1.创建分页对象，Page(page, pageSize)
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);

        //2.创建查询对象，设置查询条件
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(name != null, Setmeal::getName, name);
        wrapper.orderByDesc(Setmeal::getUpdateTime); //设置排序 按更新时间排序

        //3.直接调用分页方法
        this.page(setmealPage, wrapper);

        //优化
        //a.创建Page<SetmealDto>
        Page<SetmealDto> setmealDtoPage = new Page<>();

        //b.将Page<Setmeal>对象的所有属性拷贝给Page<SetmealDto>，排除records属性
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");

        //c.构造Page<SetmealDto>的records属性，records里面存的数据List<SetmealDto>
        List<SetmealDto> setmealDtoList = new ArrayList<>();

        //d.SetmealDto需要封装Setmeal的所有属性以及categoryName属性
        //e.根据List<Setmeal>循环遍历，将setmeal所有属性值拷贝给SetmealDto
        List<Setmeal> setmealList = setmealPage.getRecords();
        for (Setmeal setmeal : setmealList) {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(setmeal, setmealDto);
            //f.查询category分类表（根据分类id），获取分类名称封装到SetmealDto中
            Category category = categoryService.getById(setmeal.getCategoryId());
            setmealDto.setCategoryName(category.getName());
            //g.添加到List<SetmealDto>
            setmealDtoList.add(setmealDto);
        }

        //h.设置Page<SetmealDto>的records属性
        setmealDtoPage.setRecords(setmealDtoList);

        //4.返回分页结果
        return setmealDtoPage;
    }

    /**
     * 删除套餐包含菜品信息也要删除
     * @param ids
     */
    @Override
    public void deleteWithDish(List<Long> ids) {
        //0.开启事务
        //1.删除之前，需要判断这个套餐的状态是否已停售，如果是起售状态不能删除
        List<Setmeal> setmeals = this.listByIds(ids);
        for (Setmeal setmeal : setmeals) {
            if (setmeal.getStatus() == 1) {
                throw new CustomException("该套餐正在售卖中，禁止删除！");
            }
        }

        //2.直接删除setmeal基本信息数据
        this.removeByIds(ids); //update xx ... where id in (xx,xx)

        //3.根据套餐id，删除套餐菜品数据setmeal_dish
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SetmealDish::getSetmealId, ids);  //  update ... where setmeal_id in (xx,xx)
        setmealDishService.remove(wrapper);
    }
}
